/******************************************************************************

  Copyright (C), 2012-2016, ZHANGYA

 ******************************************************************************
  File Name     : debug.c
  Version       : Initial Draft
  Author        : zhangya
  Created       : 2024/2/3
  Last Modified :
  Description   : debug.c
  Function List :
  History       :
  1.Date        : 2024/2/3
    Author      : zhangya
    Modification: Created file

******************************************************************************/
#include "debug.h"
#include <stdarg.h>
#include <stdio.h>

/*--------------------------------------------------------------------*
 * $external variables                           *
 *--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*
 * $external routine prototypes                  *
 *--------------------------------------------------------------------*/
#if (DEBUG_EN > 0)
 #define _DEBUG_STRING(_fmt)		SEGGER_RTT_WriteString(0,_fmt)
 #define _DEBUG_PRINTF(...)			SEGGER_RTT_printf(0,__VA_ARGS__)
#else
 #define _DEBUG_STRING(_fmt)
 #define _DEBUG_PRINTF(...)
#endif

/*--------------------------------------------------------------------*
 * $internal routine prototypes                  *
 *--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*
 * $project-wide global variables                *
 *--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*
 * $module-wide global variables                 *
 *--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*
 * $constants                                    *
 *--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*
 * $macros                                       *
 *--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*
 * $routines' implementations                    *
 *--------------------------------------------------------------------*/
 
/*****************************************************************************
 Prototype    : debug_init
 Description  : debug init
 Input        : void  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2024/2/4
    Author       : zhangya
    Modification : Created function

*****************************************************************************/
void debug_init(void)
{
#if (DEBUG_EN > 0)
    SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
#endif
}

#if (DEBUG_EN > 0)

static char log_buf[256];

/*****************************************************************************
 Prototype    : debug_error
 Description  : debug error
 Input        : const char * file    
                const long line      
                const char * format  
                ...                  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2024/5/9
    Author       : zhangya
    Modification : Created function

*****************************************************************************/
void debug_error(const char * file, const long line, const char * format, ...)
{
    va_list args;

    /* args point to the first variable parameter */
    va_start(args, format);
    _DEBUG_PRINTF("[err]:(%s:%ld)", file, line);
    /* must use vprintf to print */
    vsnprintf(log_buf, sizeof(log_buf), format, args);
    _DEBUG_PRINTF("%s\n", log_buf);
    va_end(args);
}

/*****************************************************************************
 Prototype    : debug_string
 Description  : debug string
 Input        : const char * str  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2024/5/9
    Author       : zhangya
    Modification : Created function

*****************************************************************************/
void debug_string(const char * str)
{
	_DEBUG_STRING("[out]:");
	_DEBUG_STRING(str);
}

/*****************************************************************************
 Prototype    : debug_info
 Description  : debug info
 Input        : const char * format  
                ...                  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2024/5/9
    Author       : zhangya
    Modification : Created function

*****************************************************************************/
void debug_info(const char * format, ...)
{
    va_list args;

    /* args point to the first variable parameter */
    va_start(args, format);
    _DEBUG_STRING("[info]:");
    /* must use vprintf to print */
    vsnprintf(log_buf, sizeof(log_buf), format, args);
    _DEBUG_PRINTF("%s", log_buf);
    va_end(args);
}

/*
_DEBUG_PRINTF("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is:\r\n", flash->name, addr, size);
_DEBUG_STRING("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n");
for (i = 0; i < size; i++)
{
    if (i % 16 == 0) {
        _DEBUG_PRINTF("[%08X] ", addr + i);
    }
    _DEBUG_PRINTF("%02X ", data[i]);
    if (((i + 1) % 16 == 0) || i == size - 1) {
        _DEBUG_STRING("\r\n");
    }
}
_DEBUG_STRING("\r\n");
*/

/*****************************************************************************
 Prototype    : debug_buffer_u8
 Description  : debug buffer u8
 Input        : const char * pDes     
                const uint8_t * pBuf  
                uint16_t bufLen       
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2024/2/4
    Author       : zhangya
    Modification : Created function

*****************************************************************************/
void debug_buffer_u8(const char * pDes, const uint8_t * pBuf, const uint16_t bufLen)
{
	uint8_t ddh, ddl;
    uint16_t i = 0, j = 0;
    uint8_t szBuffer[MAX_TRACE_STR_LEN]={0};
	
	if (pDes != NULL)
        _DEBUG_STRING(pDes);
	if (bufLen == 0) {
		_DEBUG_STRING("data is null\r\n");
		return ;
	}

	for (i=0; i<bufLen; i++)
    {
        ddh = 48 + ((pBuf[i] >> 4) & 0x0f);
        ddl = 48 + (pBuf[i] & 0x0f);

        if (ddh > 57)
            ddh = ddh + 7;
        if (ddl > 57)
            ddl = ddl + 7;

        szBuffer[j++]   = ddh;
        szBuffer[j++] = ddl;
		szBuffer[j++] = ' ';

        if (j+4 >= MAX_TRACE_STR_LEN)
        {
			szBuffer[j] = 0;
            _DEBUG_STRING((const char *)szBuffer);
            j = 0;
        }
    }
    if (j < MAX_TRACE_STR_LEN)
    {
        szBuffer[j++] = '\n';
		szBuffer[j] = 0;
        _DEBUG_STRING((const char *)szBuffer);
    }
}

/*****************************************************************************
 Prototype    : debug_buffer_u16
 Description  : debug buffer u16
 Input        : const char * pDes      
                const uint16_t * pBuf  
                uint16_t bufLen        
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2024/2/4
    Author       : zhangya
    Modification : Created function

*****************************************************************************/
void debug_buffer_u16(const char * pDes, const uint16_t * pBuf, const uint16_t bufLen)
{
	uint8_t ddh, ddl, dbh, dbl;
    uint16_t i = 0, j = 0, temp;
    uint8_t szBuffer[MAX_TRACE_STR_LEN]={0};
	
	if (pDes != NULL)
        _DEBUG_STRING(pDes);
	if (bufLen == 0)
		return ;

	for (i=0; i<bufLen; i++)
    {
		temp = pBuf[i];
        ddh = 48 + ((temp >> 12) & 0x0f);
        ddl = 48 + ((temp >> 8) & 0x0f);
		dbh = 48 + ((temp >> 4) & 0x0f);
        dbl = 48 + (temp & 0x0f);

        if (ddh > 57)
            ddh = ddh + 7;
        if (ddl > 57)
            ddl = ddl + 7;
		if (dbh > 57)
            dbh = dbh + 7;
        if (dbl > 57)
            dbl = dbl + 7;

        szBuffer[j++] = ddh;
        szBuffer[j++] = ddl;
		szBuffer[j++] = dbh;
        szBuffer[j++] = dbl;
		szBuffer[j++] = ' ';

        if (j+6 >= MAX_TRACE_STR_LEN)
        {
			szBuffer[j] = 0;
            _DEBUG_STRING((const char *)szBuffer);
            j = 0;
        }
    }
    if (j < MAX_TRACE_STR_LEN)
    {
        szBuffer[j++] 	= '\n';
		szBuffer[j] 	= 0;
        _DEBUG_STRING((const char *)szBuffer);
    }
}

/*****************************************************************************
 Prototype    : debug_buffer_u32
 Description  : debug buffer u32
 Input        : const char * pDes      
                const uint32_t * pBuf  
                uint16_t bufLen        
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2024/2/4
    Author       : zhangya
    Modification : Created function

*****************************************************************************/
void debug_buffer_u32(const char * pDes, const uint32_t * pBuf, const uint16_t bufLen)
{
	uint8_t ddh, ddl, dch, dcl, dbh, dbl, dah, dal;
    uint16_t i = 0, j = 0;
    uint32_t temp;
    uint8_t szBuffer[MAX_TRACE_STR_LEN]={0};
	
	if (pDes != NULL)
        _DEBUG_STRING(pDes);
	if (bufLen == 0)
		return ;

	for (i=0; i<bufLen; i++)
    {
		temp = pBuf[i];
		ddh = 48 + ((temp >> 28) & 0x0f);
        ddl = 48 + ((temp >> 24) & 0x0f);
        dch = 48 + ((temp >> 20) & 0x0f);
        dcl = 48 + ((temp >> 16) & 0x0f);
        dbh = 48 + ((temp >> 12) & 0x0f);
        dbl = 48 + ((temp >> 8) & 0x0f);
		dah = 48 + ((temp >> 4) & 0x0f);
        dal = 48 + (temp & 0x0f);

        if (ddh > 57)
            ddh = ddh + 7;
        if (ddl > 57)
            ddl = ddl + 7;
        if (dch > 57)
            dch = ddh + 7;
        if (dcl > 57)
            dcl = ddl + 7;
		if (dbh > 57)
            dbh = dbh + 7;
        if (dbl > 57)
            dbl = dbl + 7;
        if (dah > 57)
            dah = dbh + 7;
        if (dal > 57)
            dal = dbl + 7;

        szBuffer[j++] = ddh;
        szBuffer[j++] = ddl;
		szBuffer[j++] = dch;
        szBuffer[j++] = dcl;
        szBuffer[j++] = dbh;
        szBuffer[j++] = dbl;
		szBuffer[j++] = dah;
        szBuffer[j++] = dal;
		szBuffer[j++] = ' ';

        if (j+10 >= MAX_TRACE_STR_LEN)
        {
			szBuffer[j] = 0;
            _DEBUG_STRING((const char *)szBuffer);
            j = 0;
        }
    }
    if (j < MAX_TRACE_STR_LEN)
    {
        szBuffer[j++] 	= '\n';
		szBuffer[j] 	= 0;
        _DEBUG_STRING((const char *)szBuffer);
    }
}

#endif  //#if (DEBUG_EN > 0)

